package com.cruise.h5.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cruise.common.core.util.CommonStrUtil;
import com.cruise.common.mybatis.util.CommonBeanUtil;
import com.cruise.common.web.result.Result;
import com.cruise.common.web.util.WebUtils;
import com.cruise.h5.mapper.*;
import com.cruise.h5.pojo.dto.*;
import com.cruise.h5.pojo.entity.*;
import com.cruise.h5.pojo.vo.*;
import com.cruise.h5.service.VideoService;
import com.cruise.h5.util.TimeUtile;
import com.cruise.system.userapi.entity.SysUser;
import com.cruise.system.userapi.feignapi.FeignSystemApi;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author cruise
 * @since 2021-03-25
 */
@Service
@Transactional(rollbackFor = RuntimeException.class)
public class VideoServiceImpl extends ServiceImpl<VideoMapper, Video> implements VideoService {

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private CustomizedLabelMapper customizedLabelMapper;

    @Resource
    private RecommendLabelMapper recommendLabelMapper;

    @Resource
    private VideoMapper videoMapper;

    @Resource
    private FeignSystemApi feignSystemApi;

    @Resource
    private VideoLikeRecordMapper videoLikeRecordMapper;

    @Resource
    private UserSubscribeRecordMapper userSubscribeRecordMapper;

    @Resource
    private VideoLabelRecordMapper videoLabelRecordMapper;

    @Resource
    private VideoCollectionMapper videoCollectionMapper;

    @Override
    public Result saveVideo(VideoDTO videoDTO) {

        Video video = new Video(CommonStrUtil.getPrimarykey(), WebUtils.getUserId(), WebUtils.getUserId(), new Date(), WebUtils.getUserId(), new Date());
        BeanUtils.copyProperties(videoDTO, video);
        save(video);
        return Result.success();
    }

    @Override
    public Result getVideoCategoryTree() {

        List<Category> categories = categoryMapper.selectList(new QueryWrapper<Category>().lambda().eq(Category::getPid, "0"));
        List<VideoCategoryTreeVO> videoCategoryTreeVOList  =  new ArrayList<VideoCategoryTreeVO>();

        for(Category category : categories){
            List<VideoCategoryTreeVO> subVideoCategoryTreeVOList  =  new ArrayList<VideoCategoryTreeVO>();
            VideoCategoryTreeVO videoCategoryTreeVO = new VideoCategoryTreeVO();
            BeanUtils.copyProperties(category, videoCategoryTreeVO);
            List<Category> subCategories = categoryMapper.selectList(new QueryWrapper<Category>().lambda().eq(Category::getPid, category.getId()));
            for(Category category1 : subCategories){
                VideoCategoryTreeVO videoCategoryTreeVoSub = new VideoCategoryTreeVO();
                BeanUtils.copyProperties(category1, videoCategoryTreeVoSub);
                subVideoCategoryTreeVOList.add(videoCategoryTreeVoSub);
            }
            videoCategoryTreeVO.setVideoCategoryTreeVOList(subVideoCategoryTreeVOList);
            videoCategoryTreeVOList.add(videoCategoryTreeVO);
        }
        return Result.success(videoCategoryTreeVOList);
    }

    @Override
    public Result getLabelByCategory(String categoryId) {


        List<CustomizedLabel> customizedLabels = customizedLabelMapper.selectList(new QueryWrapper<CustomizedLabel>().lambda().eq(CustomizedLabel::getUserId, WebUtils.getUserId()));

        List<RecommendLabel> recommendLabels = recommendLabelMapper.selectList(new QueryWrapper<RecommendLabel>().lambda().eq(RecommendLabel::getCategoryId, categoryId));

        VideoLabelVO videoLabelVO = new VideoLabelVO(customizedLabels, recommendLabels);

        return Result.success(videoLabelVO);
    }

    @Override
    public Result saveCoverPic(CoverPicDTO coverPicDTO) {

        Video video = new Video();
        BeanUtils.copyProperties(coverPicDTO, video);
        update(video, new QueryWrapper<Video>().lambda().eq(Video::getId, coverPicDTO.getVideoId()));
        return Result.success();
    }

    @Override
    public Integer like(LikeDTO likeDTO) {
        Integer isLike = likeDTO.getIsLike();
        if(isLike != null){
            VideoLikeRecord videoLikeRecord1 = videoLikeRecordMapper.selectOne(new QueryWrapper<VideoLikeRecord>().lambda().eq(VideoLikeRecord::getUserId, WebUtils.getUserId()).eq(VideoLikeRecord::getVideoId, likeDTO.getId()).eq(VideoLikeRecord::getType, "1"));
            if(isLike > 0){
                if(videoLikeRecord1 == null){
                    // 点赞
                    videoMapper.like(likeDTO.getId());
                    VideoLikeRecord videoLikeRecord = new VideoLikeRecord(WebUtils.getUserId(), likeDTO.getId(), 1);
                    videoLikeRecordMapper.insert(videoLikeRecord);
                }
            }else if(isLike < 0){
                if(videoLikeRecord1 != null){
                    // 取消点赞
                    videoMapper.cancelLike(likeDTO.getId());
                    videoLikeRecordMapper.delete(new QueryWrapper<VideoLikeRecord>().lambda()
                            .eq(VideoLikeRecord::getUserId, WebUtils.getUserId())
                            .eq(VideoLikeRecord::getVideoId, likeDTO.getId())
                            .eq(VideoLikeRecord::getType, 1));
                }

            }
            Video video = videoMapper.selectById(likeDTO.getId());
            return video.getLikeCount();
        }

        Integer isDisLike = likeDTO.getIsDisLike();
        if(isDisLike != null){
            VideoLikeRecord videoLikeRecord1 = videoLikeRecordMapper.selectOne(new QueryWrapper<VideoLikeRecord>().lambda().eq(VideoLikeRecord::getUserId, WebUtils.getUserId()).eq(VideoLikeRecord::getVideoId, likeDTO.getId()).eq(VideoLikeRecord::getType, "0"));
            if(isDisLike > 0){
                if(videoLikeRecord1 == null){
                    // 点踩
                    videoMapper.disLike(likeDTO.getId());
                    VideoLikeRecord videoLikeRecord = new VideoLikeRecord(WebUtils.getUserId(), likeDTO.getId(), 0);
                    videoLikeRecordMapper.insert(videoLikeRecord);
                }

            }else if(isDisLike < 0){
                if(videoLikeRecord1 != null){
                    // 取消点踩
                    videoMapper.cancelDisLike(likeDTO.getId());
                    videoLikeRecordMapper.delete(new QueryWrapper<VideoLikeRecord>().lambda()
                            .eq(VideoLikeRecord::getUserId, WebUtils.getUserId())
                            .eq(VideoLikeRecord::getVideoId, likeDTO.getId())
                            .eq(VideoLikeRecord::getType, 0));
                }
            }

            Video video = videoMapper.selectById(likeDTO.getId());
            return video.getDislikeCount();
        }
        return null;
    }

    @Override
    public Result<IPage<VideoListVO>> videoList(VideoListDTO videoListDTO) {

        if (StringUtils.isEmpty(videoListDTO.getUserId())){
            // 如果 userId 为空，默认当前用户
            videoListDTO.setUserId(WebUtils.getUserId());
        }

        Page<Video> videoPageParam = new Page<>(videoListDTO.getCurrent(), videoListDTO.getSize());
        Page<Video> videoPage =(Page<Video>)videoMapper.selectPage(videoPageParam , new QueryWrapper<Video>().lambda().eq(Video::getCreateBy, videoListDTO.getUserId()).orderByDesc(Video::getCreateDate));
        IPage<VideoListVO> videoListPageVO = CommonBeanUtil.pageVo(videoPage, VideoListVO.class);
        return Result.success(videoListPageVO);
    }

    @Override
    public Result<GetPlayVideoInfoVO> getPlayVideoInfo(String videoId) {
        GetPlayVideoInfoVO.AuthorInfo authorInfo = new GetPlayVideoInfoVO.AuthorInfo();
        GetPlayVideoInfoVO.VideoInfo videoInfo = new GetPlayVideoInfoVO.VideoInfo();
        Video video = videoMapper.selectById(videoId);
        videoInfo = CommonBeanUtil.convert(video, GetPlayVideoInfoVO.VideoInfo.class);

        String userId = videoInfo.getUserid();
        SysUser sysUser = feignSystemApi.findById(userId);
        authorInfo = CommonBeanUtil.convert(sysUser, GetPlayVideoInfoVO.AuthorInfo.class);
        String currUserId = WebUtils.getUserId();
        if(currUserId.equals(userId)){
            // 是自己的视频
            authorInfo.setIsMyself(true);
        }
        List<UserSubscribeRecord> userSubscribeRecords = userSubscribeRecordMapper.selectList(new QueryWrapper<UserSubscribeRecord>().lambda().eq(UserSubscribeRecord::getUserId, currUserId));
        authorInfo.setIsSubscribe(false);
        for(UserSubscribeRecord userSubscribeRecord : userSubscribeRecords ){
            if(userId.equals(userSubscribeRecord.getSubscribeUserId())){
                //已经订阅
                authorInfo.setIsSubscribe(true);
            }
        }
        // 后期标签放在缓存里
        List<VideoLabelRecord> videoLabelRecords = videoLabelRecordMapper.selectList(new QueryWrapper<VideoLabelRecord>().lambda().eq(VideoLabelRecord::getVideoId, videoId).orderByAsc(VideoLabelRecord::getLabelOrder));
        List<String> collect = videoLabelRecords.stream().map(VideoLabelRecord::getLabelText).collect(Collectors.toList());
        videoInfo.setLabelList(collect);
        videoInfo.setIsAlreadyLike(isAlreadyLike(videoId,WebUtils.getUserId()));
        videoInfo.setIsAlreadyDisLike(isAlreadyDisLike(videoId , WebUtils.getUserId()));
        videoInfo.setIsAlreadyCollect(isAlreadyCollect(videoId, WebUtils.getUserId()));

        return Result.success(new GetPlayVideoInfoVO(videoInfo, authorInfo));
    }

    @Override
    public Result<IPage<VideoListMainPageVO>> videoListMainPage(VideoListMainPageDTO videoListMainPageDTO) {

        Page<Video> videoPageParam = new Page<>(videoListMainPageDTO.getCurrent(), videoListMainPageDTO.getSize());
        Page<Video> videoPage =(Page<Video>)videoMapper.selectPage(videoPageParam , new QueryWrapper<Video>().lambda().orderByDesc(Video::getLikeCount));
        IPage<VideoListMainPageVO> videoListMainPageVOIPage = CommonBeanUtil.pageVo(videoPage, VideoListMainPageVO.class);
        videoListMainPageVOIPage.getRecords().forEach(item ->{
            String createBy = item.getCreateBy();
            SysUser createUser = feignSystemApi.findById(createBy);
            item.setAvatar(createUser.getAvatar());
            item.setNickname(createUser.getNickname());
            item.setCreateDateStr(TimeUtile.putDate(item.getCreateDate()));
        });
        return Result.success(videoListMainPageVOIPage);
    }

    private Boolean isAlreadyLike(String videoId, String userId ){
        VideoLikeRecord videoCommentLikeRecordLike = videoLikeRecordMapper.selectOne(new QueryWrapper<VideoLikeRecord>().lambda()
                .eq(VideoLikeRecord::getVideoId, videoId)
                .eq(VideoLikeRecord::getType, 1)
                .eq(VideoLikeRecord::getUserId,userId));
        return (videoCommentLikeRecordLike != null ? true : false);
    }

    private Boolean isAlreadyDisLike(String videoId, String userId ){
        VideoLikeRecord videoCommentLikeRecordDisLike = videoLikeRecordMapper.selectOne(new QueryWrapper<VideoLikeRecord>().lambda()
                .eq(VideoLikeRecord::getVideoId, videoId)
                .eq(VideoLikeRecord::getType, 0)
                .eq(VideoLikeRecord::getUserId, userId));
        return (videoCommentLikeRecordDisLike != null ? true : false);
    }

    private Boolean isAlreadyCollect(String videoId, String userId ){
        VideoCollection videoCollection = videoCollectionMapper.selectOne(new QueryWrapper<VideoCollection>().lambda()
                .eq(VideoCollection::getVideoId, videoId)
                .eq(VideoCollection::getUserId, userId));
        return (videoCollection != null ? true : false);
    }

}
